package info.techgeek.labs.java5Features.thread.pripority;

import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Semaphore;


public class ParaKitTaskExecutor {
        
        ConcurrentLinkedQueue<PriorityTask> highTasks = new ConcurrentLinkedQueue<PriorityTask> ();
        ConcurrentLinkedQueue<PriorityTask> mediumTasks = new ConcurrentLinkedQueue<PriorityTask> ();
        ConcurrentLinkedQueue<PriorityTask> lowTasks = new ConcurrentLinkedQueue<PriorityTask> ();
        
        Semaphore highSemaph = new Semaphore(0);
        Semaphore mediumSemaph = new Semaphore(0);
        Semaphore lowSemaph = new Semaphore(0);
        
        public void submitTask(PriorityTask task){
                switch (task.getTaskPriorityLevel()){
                case HIGH :
                        highTasks.offer(task);
                        highSemaph.release();
                        mediumSemaph.release();
                        lowSemaph.release();
                        break;
                case MEDIUM :
                        mediumTasks.offer(task);
                        mediumSemaph.release();
                        lowSemaph.release();
                        break;
                case LOW :
                        lowTasks.offer(task);
                        lowSemaph.release();
                        break;
                }
        }

        public void start(){
                //start threads for low/medium/high task.
                for (int i = 0;i<3 ; i++){
                        Thread thread = new Thread(new Runnable(){

//                                @Override
                                public void run() {
                                        
                                        while(true){
                                                try {
                                                        lowSemaph.acquire();
                                                        PriorityTask task = null;
                                                        task = highTasks.poll();
                                                        if (task == null) task = mediumTasks.poll();
                                                        if (task == null) task = lowTasks.poll();
                                                        if (task != null) task.run();
                                                } catch (InterruptedException e) {
                                                        Thread.interrupted();
                                                }
                                        }
                                }
                                
                        },"LOWTREAD" + i);
                        thread.start();
                        System.out.println("LOWTREAD" + i + " started");
                }

                //start threads for medium/high task.
                for (int i = 0;i<2 ; i++){
                        Thread thread = new Thread(new Runnable(){

//                                @Override
                                public void run() {
                                        
                                        while(true){
                                                try {
                                                        mediumSemaph.acquire();
                                                        PriorityTask task = null;
                                                        task = highTasks.poll();
                                                        if (task == null) task = mediumTasks.poll();
                                                        if (task != null) task.run();
                                                } catch (InterruptedException e) {
                                                        Thread.interrupted();
                                                }
                                        }
                                }
                                
                        },"MEDIUMTREAD" + i);
                        thread.start();
                        System.out.println("MEDIUMTREAD" + i + " started");
                }
        
                //start threads for high task.
                for (int i = 0;i<1 ; i++){
                        Thread thread = new Thread(new Runnable(){

//                                @Override
                                public void run() {
                                        
                                        while(true){
                                                try {
                                                        highSemaph.acquire();
                                                        PriorityTask task = null;
                                                        task = highTasks.poll();
                                                        if (task != null) task.run();
                                                } catch (InterruptedException e) {
                                                        Thread.interrupted();
                                                }
                                        }
                                }
                                
                        },"HIGHTREAD" + i);
                        thread.start();
                        System.out.println("HIGHTREAD" + i + " started");
                }
        }
        
}
